<template>
  <view class="container" v-if="isShow" @click.stop="isShow=false" @touchmove.stop.prevent="toMoveHandle">
    <!--    <image :src="canvasImg" mode="widthFix" class="poster-img" v-if="canvasImg" :show-menu-by-longpress="true" @click.stop="showPreview"></image>-->
    <canvas @click.stop="showPreview" canvas-id="my-canvas"
            :style="{ width: canvasStyle.width + 'px', height: canvasStyle.height + 'px'}"
            :show-menu-by-longpress="true" class="canvas" :class="{'active': activePreview}"></canvas>
    <view class="save-btn" @click.stop="saveImage" v-if="activePreview">保存图片</view>
  </view>
</template>
<script>
import {getSystem} from "@/components/hxk-house-poster/utils";

export default {
  name: "hxk-house-poster",
  props: {
    shareOptions: {
      type: Object,
      default: () => ({})
    }
  },
  data() {
    return {
      system: null, //系统信息
      canvasW: 0,
      canvasH: 0,
      ctx: null,
      isShow: false,
      canvasImg: '',
      activePreview: false,
    }
  },
  computed: {
    canvasStyle() {
      return {
        x: 0,
        y: 0,
        width: uni.upx2px(690),
        // height: Math.max(uni.upx2px(this.system.h * 0.70 * 2), uni.upx2px(1200)),
        height: uni.upx2px(1000),
        padding: uni.upx2px(20)
      }
    },
    topText() {
      return {
        title: '您的好友',
        subTitle: '给你发来了房源邀请，快来看看吧',
        titleFontSize: 18,
        subTitleFontSize: 14,
        titleColor: '#333333',
        subTitleColor: '#666666',
      }
    }
  },
  created() {
    this.system = getSystem()
  },
  methods: {
    toMoveHandle() {
    },
    // 显示
    showCanvas() {
      this.isShow = true
      this.init()
    },
    // 初始化画布
    async init() {
      uni.showLoading({
        title: '加载中...',
        mask: true
      })
      this.ctx = uni.createCanvasContext('my-canvas', this)
      //设置画布背景透明
      this.ctx.setFillStyle('rgba(255, 255, 255, 0)')
      //设置画布大小
      this.ctx.fillRect(this.canvasStyle.x, this.canvasStyle.y, this.canvasStyle.width, this.canvasStyle.height)
      //绘制圆角背景
      this.drawBackground(this.canvasStyle.x, this.canvasStyle.y, this.canvasStyle.width, this.canvasStyle.height, uni.upx2px(20), '#FFFFFF')

      //绘制顶部标题
      this.drawTopText()

      // 左边绘制产品主图、价格、标题、副标题
      this.drawProduct()
      // 右边绘制小程序码
      await this.drawQRCode()
      setTimeout(() => {
        this.ctx.draw(true, (() => {
          this.activePreview = true
          uni.hideLoading()
          console.log('画布渲染完成')
          uni.canvasToTempFilePath({
            canvasId: 'my-canvas',
            success: (res) => {
              let tempFilePath = res.tempFilePath;
              this.canvasImg = tempFilePath
              console.log('临时路径已获取')
            },
            fail: function (err) {
              console.error(err);
            }
          }, this)
        })())
      }, 500)
      //延迟渲染
      // setTimeout(() => {
      //   this.ctx.draw(true, () => {
      //     uni.hideLoading()
      //     uni.canvasToTempFilePath({
      //       canvasId: 'my-canvas',
      //       success: (res) => {
      //         let tempFilePath = res.tempFilePath;
      //         this.canvasImg = tempFilePath
      //         console.log('临时路径已获取')
      //       },
      //       fail: function (err) {
      //         console.error(err);
      //       }
      //     }, this);
      //   })
      // }, 500)
    },
    //绘制背景
    drawBackground(x, y, width, height, radius, color) {
      // 开始一个新路径
      this.ctx.beginPath();
      // 从左上角开始绘制路径
      this.ctx.moveTo(x + radius, y);
      // 绘制顶部边缘到右上角，不包括圆角
      this.ctx.lineTo(x + width - radius, y);
      // 绘制右上角的圆角部分
      this.ctx.arcTo(x + width, y, x + width, y + radius, radius);
      // 绘制右边边缘到右下角，不包括圆角
      this.ctx.lineTo(x + width, y + height - radius);
      // 绘制右下角的圆角部分
      this.ctx.arcTo(x + width, y + height, x + width - radius, y + height, radius);
      // 绘制底部边缘到左下角，不包括圆角
      this.ctx.lineTo(x + radius, y + height);
      // 绘制左下角的圆角部分
      this.ctx.arcTo(x, y + height, x, y + height - radius, radius);
      // 绘制左边边缘到左上角，不包括圆角
      this.ctx.lineTo(x, y + radius);
      // 绘制左上角的圆角部分
      this.ctx.arcTo(x, y, x + radius, y, radius);
      // 关闭路径
      this.ctx.closePath();
      // 填充圆角矩形（可选描边）
      this.ctx.fillStyle = color; // 设置填充颜色为番茄色
      this.ctx.fill(); // 填充圆角矩形
      this.ctx.draw(true)
    },
    //绘制顶部文字
    drawTopText() {
      //绘制标题
      const title = this.topText.title;
      const titleX = this.canvasStyle.x + uni.upx2px(40); // 标题左对齐的 x 坐标
      const titleY = this.canvasStyle.y + uni.upx2px(60); // 标题的 y 坐标
      // 设置粗体
      this.ctx.font = `bold ${this.topText.titleFontSize}px Arial`
      // this.ctx.setFontSize(this.topText.titleFontSize);
      this.ctx.setFillStyle(this.topText.titleColor);
      this.ctx.fillText(title, titleX, titleY);
      //绘制副标题
      const subtitle = this.topText.subTitle;
      const subtitleX = this.canvasStyle.x + uni.upx2px(40); // 副标题左对齐的 x 坐标
      const subtitleY = titleY + uni.upx2px(60); // 副标题的 y 坐标
      this.ctx.font = `${this.topText.subTitleFontSize}px Arial`
      this.ctx.setFillStyle(this.topText.subTitleColor);
      this.ctx.fillText(subtitle, subtitleX, subtitleY);
    },
    //绘制产品主图、价格、标题、副标题
    async drawProduct() {
      // 绘制产品主图
      let productImg = await this.getImageInfo(this.shareOptions.mainImg);
      const productImgX = this.canvasStyle.x + uni.upx2px(40); // 产品主图左对齐的 x 坐标
      const productImgY = this.canvasStyle.y + uni.upx2px(160); // 产品主图的 y 坐标
      const productImgW = this.canvasStyle.width - uni.upx2px(80); // 产品主图的宽度
      const productImgH = this.canvasStyle.height * 0.4; // 产品主图的高度
      this.ctx.drawImage(productImg.path, productImgX, productImgY, productImgW, productImgH);
      // 绘制标题
      const productTitle = this.shareOptions.title;
      const productTitleX = this.canvasStyle.x + uni.upx2px(40); // 标题左对齐的 x 坐标
      const productTitleY = productImgY + productImgH + uni.upx2px(60); // 标题的 y 坐标
      const productTitleW = (this.canvasStyle.width - uni.upx2px(80)) * 0.6; // 标题的宽度
      const productTitleH = await this.drawTextReturnH(this.ctx, productTitle, productTitleX, productTitleY, productTitleW, 16, '#333333', 30)
      // 绘制副标题
      const productSubTitle = this.shareOptions.subTitle;
      const productSubTitleX = productTitleX; // 副标题左对齐的 x 坐标
      const productSubTitleY = productTitleH; // 副标题的 y 坐标
      const productSubTitleW = (this.canvasStyle.width - uni.upx2px(80)) / 2; // 副标题的宽度
      const productSubTitleH = await this.drawTextReturnH(this.ctx, productSubTitle, productSubTitleX, productSubTitleY, productSubTitleW, 12, '#666666', 20)
      // 绘制价格
      const productPrice = '￥' + this.shareOptions.price + '/晚';
      const productPriceX = this.canvasStyle.x + uni.upx2px(40); // 价格左对齐的 x 坐标
      const productPriceY = productSubTitleH + uni.upx2px(20); // 价格的 y 坐标
      const productPriceW = (this.canvasStyle.width - uni.upx2px(80)) / 2; // 价格的宽度
      const productPriceH = await this.drawTextReturnH(this.ctx, productPrice, productPriceX, productPriceY, productPriceW, 16, '#FE726B', 30)
      this.ctx.draw(true)
    },
    //绘制小程序码
    async drawQRCode() {
      let path = this.base64ToFilePath(this.shareOptions.codeUrl)
      const codeX = (this.canvasStyle.width - 40) * 0.6 + uni.upx2px(40)
      const codeY = this.canvasStyle.y + uni.upx2px(160) + this.canvasStyle.height * 0.4 + uni.upx2px(40)
      const codeW = (this.canvasStyle.width * 0.4) - uni.upx2px(20)
      const codeH = (this.canvasStyle.width * 0.4) - uni.upx2px(20)
      this.ctx.drawImage(path, codeX, codeY, codeW, codeH)

      //提示文案（居中）
      this.ctx.font = `12px Arial`
      this.ctx.setFillStyle('#858585')
      this.ctx.fillText('长按识别图中小程序', codeX + uni.upx2px(20), codeY + codeH + uni.upx2px(40))
    },
    //获取图片
    getImageInfo(imgSrc) {
      return new Promise((resolve, reject) => {
        uni.getImageInfo({
          src: imgSrc,
          success: (image) => {
            resolve(image);
            console.log('获取图片成功', image)
          },
          fail: (err) => {
            reject(err);
            console.log('获取图片失败', err)
          }
        });
      });
    },
    // 绘制文字
    drawTextReturnH(ctx, text, x, y, maxWidth, fontSize, color = '#000000', lineHeight = 30, textAlign = 'left', lineNum = 2) {
      if (textAlign) {
        ctx.setTextAlign(textAlign) //设置文本的水平对齐方式  ctx.setTextAlign这个可以兼容百度小程序 ，注意：ctx.textAlign百度小程序有问题
        switch (textAlign) {
          case 'center':
            x = getSystem().w / 2
            break

          case 'right':
            x = (getSystem().w - maxWidth)
            break

          default:
            // 左对齐
            // x = (getSystem().w - maxWidth) / 2
            break
        }
      }
      let arrText = text.split('')
      let line = ''
      let arrLine = []
      for (let n = 0; n < arrText.length; n++) {
        let testLine = line + arrText[n]
        ctx.font = fontSize + 'px sans-serif' //设置字体大小，注意：百度小程序 用ctx.setFontSize设置字体大小后，计算字体宽度会无效
        ctx.setFillStyle(color) //设置字体颜色
        let metrics = ctx.measureText(testLine) //measureText() 方法返回包含一个对象，该对象包含以像素计的指定字体宽度。
        let testWidth = metrics.width
        if (testWidth > maxWidth && n > 0) {
          arrLine.push(line)
          line = arrText[n]
        } else {
          line = testLine
        }
      }
      arrLine.push(line)
      if (arrLine.length > lineNum && lineNum > 0) {
        arrLine = arrLine.slice(0, lineNum)
        // 将第n行文字的最后一个字符替换成省略号
        arrLine[lineNum - 1] = arrLine[lineNum - 1].slice(0, -1) + '...'
      }
      for (let i = 0; i < arrLine.length; i++) {
        ctx.fillText(arrLine[i], x, y)
        y += lineHeight
      }
      ctx.draw(true) //本次绘制是否接着上一次绘制。即 reserve 参数为 false，则在本次调用绘制之前 native 层会先清空画布再继续绘制；若 reserve 参数为 true，则保留当前画布上的内容，本次调用 drawCanvas 绘制的内容覆盖在上面，默认 false。
      return y
    },
    //保存图片
    saveImage() {
      //判断用户授权
      uni.getSetting({
        success(res) {
          console.log('获取用户权限', res.authSetting)
          if (Object.keys(res.authSetting).length > 0) {
            //判断是否有相册权限
            if (res.authSetting['scope.writePhotosAlbum'] === undefined) {
              //打开设置权限
              uni.openSetting({
                success(res) {
                  console.log('设置权限', res.authSetting)
                }
              })
            } else {
              if (!res.authSetting['scope.writePhotosAlbum']) {
                //打开设置权限
                uni.openSetting({
                  success(res) {
                    console.log('设置权限', res.authSetting)
                  }
                })
              }
            }
          } else {
            return
          }
        }
      })
      let that = this
      uni.canvasToTempFilePath({
        canvasId: 'my-canvas',
        quality: 1,
        complete: (res) => {
          console.log('保存到相册', res);
          uni.saveImageToPhotosAlbum({
            filePath: res.tempFilePath,
            success(res) {
              uni.showToast({
                title: '已保存到相册',
                icon: 'success',
                duration: 2000
              })
              setTimeout(() => {
                that.isShow = false
              }, 2000)
            }
          })
        }
      }, this);
    },
    // 将Base64 编码的图片数据转换为一个临时文件路径
    base64ToFilePath(base64Img) {
      const filePath = `${wx.env.USER_DATA_PATH}/temp_image.png`;
      wx.getFileSystemManager().writeFile({
        filePath: filePath,
        data: base64Img.replace(/^data:image\/\w+;base64,/, ""),
        encoding: 'base64',
        success: () => {
          console.log('文件写入成功', filePath);
        },
        fail: (err) => {
          console.error('文件写入失败', err);
        }
      });
      return filePath;
    },
    showPreview() {
      uni.previewImage({
        urls: [this.canvasImg]
      })
    }
  }
}
</script>

<style scoped lang="scss">
.container {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, .4);
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;

  .canvas {
    top: 100%;

    &.active {
      top: 0;
    }
  }

  .save-btn {
    margin-top: 35rpx;
    color: #FFFFFF;
    background: linear-gradient(to right, #FE726B, #FE956B);
    padding: 15rpx 40rpx;
    border-radius: 50rpx;
  }
}
</style>